package com.lapelife.backend.service.impl;

import com.alibaba.fastjson.JSON;
import com.lapelife.backend.common.ErrorCode;
import com.lapelife.backend.common.RedisContains;
import com.lapelife.backend.mapper.SysUserMapper;
import com.lapelife.backend.domain.entity.LoginUser;
import com.lapelife.backend.common.ResponseResult;
import com.lapelife.backend.domain.entity.SysUser;
import com.lapelife.backend.service.LoginService;
import com.lapelife.backend.utils.JwtUtils;
import com.lapelife.backend.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
public class LoginServiceImpl implements LoginService {
    private AuthenticationManager authenticationManager;

    private RedisUtil redisUtil;

    private SysUserMapper sysUserMapper;


    @Autowired
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Autowired
    public void setRedisUtil(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    @Override
    public ResponseResult<Map<String,String>> login(SysUser user) {
        System.out.println("user = " + user);
        // 将用户信息传入security进行认证
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authentication);
        // 判断用户是否认证成功
        if (Objects.isNull(authenticate)) {
            return ResponseResult.fail(401, "用户名或密码错误");
        }
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        // 将userid和用户信息存入redis
        String id = loginUser.getSysUser().getUserId().toString();
        redisUtil.set(RedisContains.USER_LOGIN + id, JSON.toJSON(loginUser));
        // 将用户id封装并返回
        Map<String, String> map = new HashMap<>();
        map.put("token", JwtUtils.getJwtToken(loginUser.getSysUser().getUserId().toString(),""));
        return ResponseResult.suc(map);
    }

    @Override
    public ResponseResult<String> logout() {
        // 获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        // 获取userid
        String id = loginUser.getSysUser().getUserId().toString();
        // 删除redis中的用户信息
        redisUtil.del(RedisContains.USER_LOGIN + id);
        return ResponseResult.suc("成功退出登录");
    }

    @Override
    @Transactional
    public ResponseResult<Map<String ,String>> register(SysUser user) {
        // 验证表单是否正确
        if (user.getPassword() == null || user.getUserName() == null) {
            return ResponseResult.fail(ErrorCode.PARAMS_ERROR);
        }
        // 验证是否存在相同用户
        SysUser sysUser = sysUserMapper.selectOneByUserName(user.getUserName());
        if (!Objects.isNull(sysUser)) {
            return ResponseResult.fail(5500,"用户已存在,请输入新的用户名");
        }
        // 对密码进行加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encode = passwordEncoder.encode(user.getPassword());
        // 配置用户默认信息
        sysUser = new SysUser();
        sysUser.setUserName(user.getUserName());
        sysUser.setNickName("");
        sysUser.setPassword(encode);
        sysUser.setUserType("10");
        sysUser.setCreateBy(user.getCreateBy());
        // 添加用户
        sysUserMapper.insert(sysUser);
        // 为用户添加默认角色
        sysUserMapper.addDefaultUserRole(sysUser.getUserId());
        return login(user);
    }
}
